/*
 * Copyright (c) 1994, 2004, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */

package java.io;

/**
 * 这个抽象类是所有表示字节输出流的类的超类。
 * 输出流接受输出字节并将其发送到某个接收器。
 * <p>
 * 需要定义OutputStream子类的应用程序必须
 * 始终至少提供一个write(int)方法。
 *
 * @author  Arthur van Hoff
 * @see     java.io.BufferedOutputStream
 * @see     java.io.ByteArrayOutputStream
 * @see     java.io.DataOutputStream
 * @see     java.io.FilterOutputStream
 * @see     java.io.InputStream
 * @see     java.io.OutputStream#write(int)
 * @since   JDK1.0
 */
public abstract class OutputStream implements Closeable, Flushable {
    /**
     * 将指定的字节写入此输出流。
     * 写的一般约定是将一个字节写入输出流。
     * 要写入的字节是参数b的8个低阶位，而忽略b的24个高阶位。
     * <p>
     * OutputStream的子类必须提供此方法的实现。
     *
     * @param      b   the <code>byte</code>.
     * @exception  IOException  if an I/O error occurs. In particular,
     *             an <code>IOException</code> may be thrown if the
     *             output stream has been closed.
     */
    public abstract void write(int b) throws IOException;

    /**
     * 将指定字节数组中的b.length个字节写入此输出流。
     * write(b)的一般约定是，它应该具有与调用写(b, 0, b.length)完全相同的效果。
     *
     * @param      b   the data.
     * @exception  IOException  if an I/O error occurs.
     * @see        java.io.OutputStream#write(byte[], int, int)
     */
    public void write(byte b[]) throws IOException {
        write(b, 0, b.length);
    }

    /**
     * 将从指定字节数组的off开始的len字节写入此输出流。
     * write(b, off, len)的一般约定是数组b中的一些字节按顺序写入输出流;
     * 元素b[off]是该操作写入的第一个字节，而b[off+len-1]是该操作写入的最后一个字节。
     * <p>
     * OutputStream的写方法调用write(int)方法。
     * 鼓励子类重写此方法并提供更有效的实现。
     * <p>
     * 如果b为null，则抛出NullPointerException。
     * <p>
     * 如果off是负数，或者len是负数，或者off+len大于数组b的长度，
     * 那么就会抛出一个IndexOutOfBoundsException。
     *
     * @param      b     the data.
     * @param      off   the start offset in the data.
     * @param      len   the number of bytes to write.
     * @exception  IOException  if an I/O error occurs. In particular,
     *             an <code>IOException</code> is thrown if the output
     *             stream is closed.
     */
    public void write(byte b[], int off, int len) throws IOException {
        if (b == null) {
            throw new NullPointerException();
        } else if ((off < 0) || (off > b.length) || (len < 0) ||
                   ((off + len) > b.length) || ((off + len) < 0)) {
            throw new IndexOutOfBoundsException();
        } else if (len == 0) {
            return;
        }
        // 不断调用write(int)
        for (int i = 0 ; i < len ; i++) {
            write(b[off + i]);
        }
    }

    /**
     * 刷新此输出流，并强制将所有缓冲的输出字节写入。
     * flush的一般约定是，调用它意味着，如果任何先前写入的字节已经被
     * 输出流的实现缓冲，那么这些字节应该立即被写入它们的预期目的地。
     * <p>
     * 如果流的预期目标是底层操作系统提供的一个抽象，
     * 例如一个文件，那么刷新流只保证以前写入流的字节被传递到操作系统进行写入;
     * 它不能保证它们实际被写入物理设备，如磁盘驱动器。
     * <p>
     * OutputStream的flush方法什么都不做
     *
     * @exception  IOException  if an I/O error occurs.
     */
    public void flush() throws IOException {
    }

    /**
     * 关闭此输出流并释放与此流关联的任何系统资源。
     * close的一般约定是关闭输出流。
     * 关闭的流不能执行输出操作，也不能重新打开。
     * <p>
     * OutputStream的close方法什么都不做
     *
     * @exception  IOException  if an I/O error occurs.
     */
    public void close() throws IOException {
    }

}
